package demo2;
//单例模式
public class SingleLazy {
    private static volatile SingleLazy instance = null;

    /**
     * 这里加volatile就是为了防止指令重排序所带来的半初始化的问题
     * 这里的new SingleLazy() 分为三步
     * 1.给他分配内存
     * 2.初始化
     * 3.将引用指向内存地址
     * 如果没有用volatile有可能发生指令重排序，在还没有初始化时候就直接将引用指向了内存地址
     * 此时其他的线程调取get的方法获取到了一个还没有初始化的instance会造成线程安全问题，
     * 空指针异常NPE
     * 对于多线程同时使用的变量我们尽量加上volatile，不仅保证了可见性，也保证了指令重排序的问题
     * volatile修饰的变量，对这个变量修改的代码会被禁止指令重排序，且由于内存屏障前后的普通读写也会被禁止重排序
     */
    private SingleLazy() {}

    public static SingleLazy getInstance() {
        if (instance == null) {
            synchronized (SingleLazy.class) {
                if (instance == null) {
                    instance = new SingleLazy();
                }
            }
        }
        return instance;
    }

}

